package server

import (
	"log"
	"net/http"

	"github.com/coder/websocket"
	"github.com/coder/websocket/wsjson"
	"github.com/go-programing-tour-book/chatroom/logic"
)

func webSocketHandleFunc(w http.ResponseWriter, r *http.Request) {
	//Accept 从客户端接收 WebSocket握手，并将连接升级到WebSocket
	//如果Arigin域的主机不同，Accpet将拒绝握手，除非设置了
	//InsecureSkipVerify 选项(通过第三个参数，AcceptOptions 来设置)
	//换句话说，默认情况下，它不允许跨源请求，如果发生错误，Accept将始终写入适当的响应
	conn, err := websocket.Accept(w, r, &websocket.AcceptOptions{InsecureSkipVerify: true})
	if err != nil {
		log.Println("websocket accept error: ", err)
		return
	}

	//1. 新用户进来，构建该用户的实例
	token := r.FormValue("token")
	nickname := r.FormValue("nickname")
	if l := len(nickname); l < 2 || l > 20 {
		log.Println("nickname illegal: ", nickname)
		wsjson.Write(r.Context(), conn, logic.NewErrorMessage("该昵称已经已存在！"))
		conn.Close(websocket.StatusUnsupportedData, "nickname exists!")
		return
	}
	if !logic.BroadCaster.CanEnterRoom(nickname) {
		errMsg := logic.NewErrorMessage("该昵称已存在")
		wsjson.Write(r.Context(), conn, errMsg)
		conn.Close(websocket.StatusUnsupportedData, "nickname exists!")
		return
	}

	user := logic.NewUser(conn, nickname, token, r.RemoteAddr)

	//2. 开启给用户发送消息的goroutine
	go user.SendMessage(r.Context())

	//3. 给新用户发送欢迎消息
	logic.BroadCaster.Broadcast(logic.NewUserEnterMessage(user))
	user.AddUserMessage(logic.NewWelcomeMessage(user))

	//4. 将该用户加入广播器的用户列表
	logic.BroadCaster.UserEntering(user)
	log.Println("user:", nickname, "joins chat")

	//5. 接收用户消息
	err = user.ReceiveMessage(r.Context())

	//6. 用户离开
	logic.BroadCaster.UserLeaving(user)
	msg := logic.NewUserLeaveMessage(user)
	logic.BroadCaster.Broadcast(msg)
	log.Println("user:", nickname, "leave chat")
	//根据读取时的错误执行不同的Close
	if err == nil {
		conn.Close(websocket.StatusNormalClosure, "")
	} else {
		log.Println("read from clien error:", err)
		conn.Close(websocket.StatusInternalError, "Read from client error")
	}

}
